import { makeAutoObservable, observable } from 'mobx';
import * as api from './api';
import { ENUMS } from './definitions';

export default class ActivityStore {
  _args = {
    search: {
    },
    pg: {
      page: 0,
      sort: ['crDate;desc'],
      size: 10,
    },
  };
  total = 0;
  data = [];
  loading = false;
  company = [];
  prices = [];
  coupons = [];
  couponsApplies = [];
  channelTypes = [];
  activities = [];
  couponsBags = [];
  _tabState = '1';

  constructor(rootStore) {
    this.rootStore = rootStore;
    makeAutoObservable(this, { rootStore: false });
  }

  /**
   * 使用设置的请求参数和分页配置请求列表数据
   * 分页参数为空时保持当前分页配置
   * @param {object} pgInfo 分页参数
   */
  * query(pgInfo) {
    _.mergeWith(this._args.pg, pgInfo, (o, s) => (_.isArray(o) ? s : undefined)); // 数组直接赋值，不合并
    const { search, pg } = toJS(this._args);
    search.type = this._tabState;
    if (!pg.sort?.length) delete pg.sort;
    this.loading = true;
    try {
      this.total = yield api.count({ search });
      const res = yield api.search({ search, pg });
      // eslint-disable-next-line @iceworks/best-practices/recommend-polyfill
      const results = yield Promise.allSettled(res.map(async (p) => {
        try {
          const r = await api.getActivityCfg(p.id);
          return { ...p, rules: r?.decisionResults?.cfg?.result || {} };
        } catch (error) {
          return { ...p, error: true };
        }
      }));
      this.data = results.map((result) => ({
        ...result.value,
        rules: result.error ? {} : result.value.rules,
      }));
      return this.data;
    } finally {
      this.loading = false;
    }
  }

  * get(id) {
    const res = yield api.get(id);
    return observable(res);
  }

  * update(activity) {
    yield api.update(activity);
    yield this.query();
  }

  * create(activity) {
    yield api.create(activity);
    yield this.query();
  }

  * remove(activity) {
    yield api.remove(activity.id);
    yield this.query();
  }

  * batchApply(activity) {
    yield api.batchApply(activity);
    yield this.query();
  }

  * getCoupons(search) {
    const res = yield api.getCoupons(search);
    this.coupons = res.map((item) => ({
      label: item.name,
      value: item.batchId,
    }));
  }

  * getCouponsApplies(search) {
    const res = yield api.getCouponsApplies(search);
    const coupons = res.map((item) => ({
      label: item.couponBatchName,
      value: item.couponBatchId,
      total: item.requestedQuantity,
      done: false,
      couponBatchName: item.couponBatchName,
    }));
    return coupons;
  }

  * getCouponAPPlies(search) {
    const res = yield api.getCouponAPPlies(search);
    const toggleCoupons = res.map((item) => ({
      label: item.couponBatchName,
      value: item.couponBatchId,
      id: item.couponBatchId,
      count: item.requestedQuantity,
    }));
    return toggleCoupons;
  }

  * getCouponBags(search) {
    const res = yield api.getCouponBags(search);
    return res.map((item) => ({
      ...item,
      check: false,
      done: false,
    }));
  }

  async getURL(id, scene, v) {
    try {
      const res = await api.getQCexterior({
        path: `${ENUMS.path[v]}?activityId=${id}&scene=activity:${scene}`,
        env_version: global.ENV_VERSITION[global.ENV],
      });
      const blob = new Blob(
        res.map((buf) => Uint8Array.from(buf.data).buffer),
        {
          type: 'image/jpeg',
        },
      );
      const objectUrl = URL.createObjectURL(blob);
      return objectUrl;
    } catch (error) {
      console.log('🚀 _ file: ActivityStore.js:145 _ ActivityStore _ error:', error);
      throw error;
    }
  }

  * getClientCouponBags(search) {
    const res = yield api.getClientCouponBags(search);
    return res.map((item) => ({
      ...item,
      check: false,
      done: false,
    }));
  }

  * substitutionCoupon(search) {
    yield api.substitutionCoupon(search);
    yield this.query();
  }

  * couponTransfer(data) {
    yield api.couponTransfer(data);
    yield this.query();
  }

  * getCouponInfo(search) {
    return yield api.getCouponInfo(search);
  }

  * updateState(activity) {
    const { enabled } = activity;
    yield api.update({ ...activity, enabled: !enabled });
    yield this.query();
  }

  * getUserMobile(v) {
    const info = yield api.getUserMobile(v);
    return info;
  }

  * uploadRule(fileData) {
    yield api.uploadRule(fileData);
    yield this.query();
  }

  * getOrderCount(args) {
    return yield api.getOrderCount(args);
  }

  * getDicts(id) {
    const types = yield api.getTopItems(id);
    const selectTypes = types.map((item) => ({
      label: item.name,
      value: item.itemId,
    }));
    this.channelTypes = selectTypes;
  }

  * sendCoupon(data) {
    yield api.sendCoupon(data);
    yield this.query();
  }

  * getActivities(search) {
    const res = yield api.getActivities(search);
    this.activities = res.map((item) => ({
      label: item.name,
      value: item.id,
    }));
  }

  * channelPrice(id) {
    const price = yield api.getChanelPrice(id);
    price.forEach((item) => {
      // 解析 items 数组中每个对象的 description 属性为 JSON 对象
      item.items.forEach((itemObj) => {
        // eslint-disable-next-line no-param-reassign
        itemObj.description = JSON.parse(itemObj.description);
      });
    });
    const keyPrice = price.map((item, index) => ({
      ...item,
      key: String(index),
    }));
    this.prices = keyPrice;
  }

  * addProfitShare(args) {
    const { id, independentAccount } = args;
    const res = yield api.addProfitShare('activity', id, independentAccount.period || '1');
    const { imgUrl, mpAppId, baseUrl } = global.getEnvCfg();
    // 动态展示小程序链接
    const text = encodeURIComponent(`${imgUrl}/mp/?appId=${mpAppId}&sid=${res.sid}`);
    const url = `${baseUrl}/api/files/qrcode?text=${text}&height=300&width=300`;
    return url;
  }

  * getCompany(id) {
    const typeList = yield api.getCompany(id);
    const selectData = typeList.map((item) => {
      return ({
        label: item.name,
        value: item.id,
      });
    });
    this.company = selectData;
  }

  * getBatchApply(id) {
    return yield api.getBatchApply(id);
  }

  * getLogs(search) {
    return yield api.getLogs(search);
  }

  * sendNotify(args) {
    yield api.sendNotify(args);
    yield this.query();
  }

  * sendCouponBag(data) {
    yield api.sendCouponBag(data);
    yield this.query();
  }

  * getCustomerService(args) {
    const res = yield api.getCustomerService(args);
    const toggleList = res.map(({ title, id }) => ({ label: title, value: id }));
    return toggleList;
  }

  * getActivityCustomer(args) {
    const res = yield api.getActivityCustomer(args);
    const toggleList = res.map(({ customerFullName, customerUsername }) => ({ label: customerFullName, value: customerUsername }));
    return toggleList;
  }

  async getCommandCode(scene, id, key) {
    try {
      const res = await api.getCommandCode({
        scene: `activity:${scene}`,
        activityId: id,
        path: `page://${ENUMS.path[key]}`,
      });
      return res;
    } catch (error) {
      console.log('🚀 _ file: ActivityStore.js:286 _ ActivityStore _ error:', error);
      throw error;
    }
  }

  * getSceneInfo(args) {
    return yield api.getSceneInfo(args);
  }

  * getActivesList(args) {
    return yield api.getActivesList(args);
  }

  * getActivesStatistic(args) {
    return yield api.getActivesStatistic(args);
  }

  priceIdx(i, page, size) {
    return page * size + i + 1;
  }

  idx(i) {
    return this._args.pg.page * this._args.pg.size + i + 1;
  }

  get api() {
    return api;
  }

  get pg() {
    return this._args.pg;
  }

  set pg(pg) {
    this.query({ ...pg });
  }

  get tabStatus() {
    return this._tabState;
  }

  set tabStatus(value) {
    this._tabState = value;
    this._args.pg.page = 0;
    this.query({ page: 0 });
  }

  get search() {
    this._args.pg.page = 0;
    return this._args.search;
  }

  set search(search) {
    this._args.pg.page = 0;
    this._args.search = search;
    this.query({ page: 0 });
  }

  get tableSort() {
    if (this._args.pg.sort?.length) {
      const [fn, dir] = this._args.pg.sort[0].split(';');
      return { [fn]: dir };
    }
    return undefined;
  }
}
